<template>
  <div class="flex-col text-justify py-[2px]">
    <div v-for="(option,index) in options" 
      :key="option[computedProps.label as string] + option[computedProps.value as string] + index" 
      :class="['flex-col h-auto flex-grow-0 flex-shrink-0 py-[2px] px-[4px]']">
      <div v-if="!isShrink" :class="[
          valuePath[level]==option[computedProps.value as string]?'tree-menu':'',
          value == option[computedProps.value] ?'bg-p-10 text-white':'text-[#303133] hover:bg-p-10',
          'flex-row items-center cursor-pointer rounded text-sm transition-all duration-200 h-40']"
        @click.stop="buttonClick(option,index)">
        <span class="h-full" :style="{width:level*10+'px'}"></span>
        <el-tooltip :disabled="!isShrink" :content="option[computedProps.label as string] || option[computedProps.value as string]" placement="right">
          <span 
            :class="[
              option[computedProps.icon as string]!=''?option[computedProps.icon as string]:'icon-type_line',
              value == option[computedProps.value] ?'text-white':'text-[#FFFFFF88]',
              'tree-menu-icon w-[36px] h-[36px] flex-col items-center justify-center iconfont font-normal text-xl']">
          </span>
        </el-tooltip>
        <span v-if="!isShrink" class="grow-1 w-0 text-ellipsis h-full items-center flex-row">
          <span class="tree-menu-label text-white text-ellipsis overflow-hidden w-0 whitespace-nowrap flex-grow-1 select-none">
            {{option[computedProps.label as string] || option[computedProps.value as string]}}
          </span>
        </span>
        <span v-if="!isShrink" class="tree-menu-side w-15 h-15 flex-col items-center justify-center iconfont mr-10 scale-75 text-xs" 
          :class="[option[computedProps.children as string] && option[computedProps.children as string].length > 0 ? 'icon-arrowR rotate-90 ':'']">
        </span>
      </div>

      <div v-if="isShrink"
        :ref="option[computedProps.value]"
        :class="[
          valuePath[level]==option[computedProps.value as string]?'tree-menu':'',
          value == option[computedProps.value] ?'bg-p-10 text-white':'text-[#909399] hover:bg-p-1',
          'flex-row items-center cursor-pointer rounded text-sm transition-all duration-200 h-[36px]'
        ]"
        @click.stop="buttonClick(option,index)">
        <el-popover
          ref="popoverRef"
          popper-class="tree-menu-propover"
          :visible="currentIndex.includes(option[computedProps.value as string]+index) && option[computedProps.children as string] && option[computedProps.children as string].length > 0"
          trigger="click"
          width="180"
          appendTo=".theme-color"
          placement="right">
          <template v-slot:reference>
            <div class="w-full h-full flex-row items-center">
              <el-tooltip v-if="level!=0 || option[computedProps.icon as string]" :disabled="!isShrink||level!=0" :content="option[computedProps.label as string] || option[computedProps.value as string]" placement="right">
                <span ref="buttonRef" class="tree-menu-icon w-[36px] h-[36px] flex-col items-center justify-center iconfont font-normal text-xl" 
                  :class="[option[computedProps.icon as string]!='' ? option[computedProps.icon as string]:'icon-sub-sm']">
                </span>
              </el-tooltip>
              <span v-if="level!=0" class="flex-grow-1 w-0 text-ellipsis h-full items-center flex-row">
                <span class="tree-menu-label text-ellipsis overflow-hidden w-0 whitespace-nowrap flex-grow-1">
                {{option[computedProps.label as string] || option[computedProps.value as string]}}
                </span>
              </span>
              <span v-if="level!=0" class="tree-menu-side w-15 h-15 flex-col items-center justify-center iconfont mr-10 scale-75 text-xs" 
                :class="[option[computedProps.children as string] && option[computedProps.children as string].length > 0 ? 'icon-arrowR ':'']">
              </span>
            </div>
          </template>
          <vmo-tree-menu
            v-if="currentIndex.includes(option[computedProps.value as string]+index) && option[computedProps.children as string] && option[computedProps.children as string].length > 0"
            :value = "value"
            :isShrink="isShrink" 
            :options="option[computedProps.children as string]"
            :value-path="valuePath"
            :props="props"
            :level="level+1"
            :is-serial-expanded="isSerialExpanded"
            class="h-auto flex-shrink-0"
            @update:value="buttonClick($event.option,$event.index)">
          </vmo-tree-menu>
        </el-popover>
      </div>
      <!--  -->
      <vmo-transition v-if="!isShrink" name="growy" :duration="{enter:300,leave:200}">
        <div v-if="currentIndex.includes(option[computedProps.value as string]+index) && option[computedProps.children as string]" class="h-auto flex-shrink-0 flex-col overflow-hidden">
          <vmo-tree-menu
            :value = "value"
            :isShrink="isShrink" 
            :options="option[computedProps.children as string]"
            :value-path="valuePath"
            :props="props"
            :level="level+1"
            :is-serial-expanded="isSerialExpanded"
            class="h-auto flex-shrink-0"
            @update:value="buttonClick($event.option,$event.index)">
          </vmo-tree-menu>
        </div>
      </vmo-transition>
    </div>
  </div>
</template>

<style lang="css">
.tree-menu-propover.el-popover.el-popper{
  padding: 0px !important;
}
</style>

<script lang="ts">
import * as R from "ramda";
import { defineComponent, ref, computed } from 'vue';
import type { PropType, Ref } from 'vue';
import { ElTooltip, ElPopover } from "element-plus";

export default defineComponent({
  name:'vmo-tree-menu',
  components:{ ElTooltip, ElPopover},
  props:{
    options:{
      type:Array as PropType<any[]>,
      default:()=>[]
    },
    isShrink:{
      type:Boolean as PropType<boolean>,
      default:false,
    },
    value:{
      type:String as PropType<string>,
      default:''
    },
    props:{
      type:Object as PropType<{
        label?:string,
        value?:string,
        icon?:string,
        children?:string
      }>,
      default:()=>({})
    },
    valuePath:{
      type:Array as PropType<string[]>,
      default:()=>[]
    },    
    heightLightClass:{
      type:String as PropType<string>,
      default:''
    },
    isSerialExpanded:{ // 是否为串行展开 及每次只展开一条
      type:Boolean as PropType<boolean>,
      default:false,
    },
    level:{
      type:Number as PropType<number>,
      default:0
    },
  },
  emits:['update:value'], // v-model 写法
  setup(props,context) {
    const currentIndex:Ref<(string|number)[]> = ref([]);
    const buttonRef = ref()
    const computedProps = computed(()=>{
      return R.mergeAll([{label:'label',value:'value',icon:'icon',children:'children'},props.props])
    })
    function buttonClick(option:any,index:number){
      const cindex = currentIndex.value.indexOf(option[computedProps.value.value as string]+index);
      if(props.isSerialExpanded || props.isShrink){
        if(cindex >= 0 ){
          currentIndex.value =[]
        }else{
          currentIndex.value = [option[computedProps.value.value as string]+index]
        }
      }else{
        cindex >= 0 ? currentIndex.value.splice(cindex,1):currentIndex.value.push(option[computedProps.value.value as string]+index)
      }
      if(!option[computedProps.value.children as string]||option[computedProps.value.children as string].length <=0 ){
        context.emit('update:value',{index,option});
      }
    };
    return {
      currentIndex,
      computedProps,
      buttonRef,
      buttonClick,
    }
  },
})
</script>

